﻿Imports Microsoft.VisualBasic
Imports System.ComponentModel
Imports System.Drawing
Imports System

 <TypeConverter(GetType(DisplayedFormatPropertiesConverter))> _
Public Class DisplayedFormatProperties

   Friend NIB As NumericInputBox
   Private _BlankZero As Boolean
   Private _Format As NIBFormat

   Private _CustomNumberFormat As String
   Private _FormattingCulture As NIBCulturePreference
   Private _UseAlternativeColorsForNegative As Boolean
   Private _SpecifiedCulture As Globalization.CultureInfo
   Private _NegativeForegroundColor As Color
   Private _NegativeBackgroundColor As Color

   Private _FormatCultureInForce As System.Globalization.CultureInfo
   Friend FormattingSupressed As Boolean

   Friend Sub New(ByVal NIB As NumericInputBox)
      Me.NIB = NIB
      Me._BlankZero = True
      Me._Format = NIBFormat.General
      Me._CustomNumberFormat = String.Empty
      Me._FormattingCulture = NIBCulturePreference.Application
      Me._UseAlternativeColorsForNegative = False
      Me._SpecifiedCulture = Globalization.CultureInfo.CurrentCulture
      Me._NegativeBackgroundColor = SystemColors.Window
      Me._NegativeForegroundColor = SystemColors.WindowText
      SetInForceCulture()
   End Sub

   Public Enum NIBFormat
      '''<summary>General - Use the String Format "G" Specifier</summary>
      General
      '''<summary>Custom - Use User Define Format String</summary>
      Custom
      '''<summary>None - Leave Text As Entered</summary>
      None
   End Enum

   Public Enum NIBCulturePreference
      Application
      Invariant
      Specify
   End Enum

   Friend Sub updateDisplayedText()
      If Not NIB.Focused AndAlso Not FormattingSupressed Then
         NIB.SetText = DisplayedFormatProperties.FormatValue(NIB.Value, NIB)
      End If
   End Sub

   <Description("If value is zero, leave box blank")> _
   <DisplayName("1. Display empty box for Zero")> _
   <NotifyParentProperty(True)> _
   Public Property BlankZero() As Boolean
      Get
         Return _BlankZero
      End Get
      Set(ByVal value As Boolean)
         _BlankZero = value
         updateDisplayedText()
      End Set
   End Property

   <DisplayName("3a. Number Format to use")> _
   <NotifyParentProperty(True)> _
   Public Property Format() As NIBFormat
      Get
         Return _Format
      End Get
      Set(ByVal value As NIBFormat)
         If Not [Enum].IsDefined(GetType(NIBFormat), value) Then
            Throw New ArgumentException("Invalid NIBFormat specified for " & NIB.Name)
         Else
            _Format = value
         End If
         updateDisplayedText()
      End Set
   End Property 'Format

   <DisplayName("3b. Custom Number Format String")> _
   <NotifyParentProperty(True)> _
   Public Property CustomNumberFormat() As String
      Get
         Return _CustomNumberFormat
      End Get
      Set(ByVal value As String)
         Try
            Dim s As String = String.Format(value, NIB.Value)
         Catch ex As Exception

         End Try
         _CustomNumberFormat = value
         updateDisplayedText()
      End Set
   End Property 'CustomFormat

   <DisplayName("2a. Number Format Culture")> _
   <Description("Culture to use for formatting." & vbCrLf & _
                "Also controls Decimal Mark and Digit group character.")> _
   <NotifyParentProperty(True)> _
   Public Property FormattingCulture() As NIBCulturePreference
      Get
         Return _FormattingCulture
      End Get
      Set(ByVal value As NIBCulturePreference)
         _FormattingCulture = value
         SetInForceCulture()
         updateDisplayedText()
      End Set
   End Property 'FormattingCulture

   <DisplayName("2b. Specified Number Format Culture")> _
   <Description("Specific culture to use for Number Formatting." & _
                "May not be a neutral culture")> _
   <NotifyParentProperty(True)> _
   Public Property SpecifiedCulture() As Globalization.CultureInfo
      Get
         Return _SpecifiedCulture
      End Get
      Set(ByVal value As Globalization.CultureInfo)
         If value.IsNeutralCulture Then
            Throw New ArgumentException("Please specify a specific culture." & _
                                         value.Name & " is a neutral culture and may not " & _
                                         "be used for number formating")
         End If
         _SpecifiedCulture = value
         SetInForceCulture()
         updateDisplayedText()
      End Set
   End Property 'SpecifiedCulture

   <DisplayName("4a. Use Alt. Colors for Negative Value")> _
   <NotifyParentProperty(True)> _
   Public Property UseAlternativeColorsForNegative() As Boolean
      Get
         Return _UseAlternativeColorsForNegative
      End Get
      Set(ByVal value As Boolean)
         _UseAlternativeColorsForNegative = value
         updateDisplayedText()
      End Set
   End Property 'UseAlternativeColorsForNegative

   <DisplayName("4b. Negative Value - Foreground")> _
   <NotifyParentProperty(True)> _
   Public Property NegativeForegroundColor() As Color
      Get
         Return _NegativeForegroundColor
      End Get
      Set(ByVal value As Color)
         _NegativeForegroundColor = value
         updateDisplayedText()
      End Set
   End Property 'NegativeForegroundColor

   <DisplayName("4c. Negative Value - Background")> _
   <NotifyParentProperty(True)> _
   Public Property NegativeBackgroundColor() As Color
      Get
         Return _NegativeBackgroundColor
      End Get
      Set(ByVal value As Color)
         _NegativeBackgroundColor = value
         updateDisplayedText()
      End Set
   End Property 'NegativeBackgroundColor

   Friend Shared Function FormatValue(ByVal value As ValueType, ByVal nib As NumericInputBox, Optional ByVal GenericOverride As Boolean = False) As String

      If nib.DisplayedFormatProperties.UseAlternativeColorsForNegative Then
         If NumericInputBox.A_IsLessThan_B(value, 0, nib.TrueSystemTypeCode) Then
            nib.SetNegativeColors()
         Else
            nib.SetBaseColors()
         End If
      End If

      If nib.DisplayedFormatProperties.BlankZero AndAlso NumericInputBox.A_IsEqualTo_B(value, 0, nib.TrueSystemTypeCode) Then
         Return String.Empty
      End If

      Dim fmt As String = "G"
      If Not GenericOverride Then
         Select Case nib.DisplayedFormatProperties._Format
            Case NIBFormat.None
               Return nib.PreviouslyEnteredText

            Case NIBFormat.Custom
               fmt = nib.DisplayedFormatProperties._CustomNumberFormat
         End Select
      End If

      Dim cultinfo As System.Globalization.CultureInfo = System.Globalization.CultureInfo.InvariantCulture
      Select Case nib.DisplayedFormatProperties.FormattingCulture
         Case NIBCulturePreference.Application
            cultinfo = My.Application.Culture
         Case NIBCulturePreference.Specify
            cultinfo = nib.DisplayedFormatProperties.SpecifiedCulture
      End Select

      Select Case Type.GetTypeCode(nib.SystemType)
         Case TypeCode.Int16 : Return CType(value, System.Int16).ToString(fmt, cultinfo)
         Case TypeCode.Int32 : Return CType(value, System.Int32).ToString(fmt, cultinfo)
         Case TypeCode.Int64 : Return CType(value, System.Int64).ToString(fmt, cultinfo)
         Case TypeCode.UInt16 : Return CType(value, System.UInt16).ToString(fmt, cultinfo)
         Case TypeCode.UInt32 : Return CType(value, System.UInt32).ToString(fmt, cultinfo)
         Case TypeCode.UInt64 : Return CType(value, System.UInt64).ToString(fmt, cultinfo)
         Case TypeCode.Single : Return CType(value, System.Single).ToString(fmt, cultinfo)
         Case TypeCode.Double : Return CType(value, System.Double).ToString(fmt, cultinfo)
         Case TypeCode.Decimal : Return CType(value, System.Decimal).ToString(fmt, cultinfo)
         Case TypeCode.Byte : Return CType(value, System.Byte).ToString(fmt, cultinfo)
         Case TypeCode.SByte : Return CType(value, System.SByte).ToString(fmt, cultinfo)
         Case Else : Return value.ToString() ' added just get rid of IDE warning
      End Select
   End Function

   Friend ReadOnly Property FormatCultureInForce() As System.Globalization.CultureInfo
      Get
         Return _FormatCultureInForce
      End Get
   End Property 'FormatCultureInForce

   Private Sub SetInForceCulture()
      Select Case _FormattingCulture
         Case NIBCulturePreference.Application
            _FormatCultureInForce = My.Application.Culture
         Case NIBCulturePreference.Invariant
            _FormatCultureInForce = System.Globalization.CultureInfo.InvariantCulture
         Case NIBCulturePreference.Specify
            _FormatCultureInForce = _SpecifiedCulture
      End Select
   End Sub

End Class
